package cn.iniche;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.net.http.SslError;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.DownloadListener;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;

import com.download.library.DownloadListenerAdapter;
import com.download.library.DownloadTask;
import com.download.library.Extra;
import com.download.library.ResourceRequest;
import com.google.android.material.appbar.AppBarLayout;
import com.just.agentweb.AbsAgentWebSettings;
import com.just.agentweb.AgentWeb;
import com.just.agentweb.DefaultDownloadImpl;
import com.just.agentweb.DefaultWebClient;
import com.just.agentweb.IAgentWebSettings;
import com.just.agentweb.NestedScrollAgentWebView;
import com.just.agentweb.WebChromeClient;
import com.just.agentweb.WebListenerManager;
import com.just.agentweb.WebViewClient;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLEncoder;

import javax.microedition.util.ContextHolder;

import cn.iniche.utils.StringUtils;
import ru.playsoftware.j2meloader.MainActivity;
import ru.playsoftware.j2meloader.R;
import ru.playsoftware.j2meloader.config.Config;

public class WebActivity extends AppCompatActivity {

    private static final String TAG = "WebActivity";
    private static final String MAIN_URL = "https://iniche.cn/games/?system=J2ME";
    private static final String SEARCH_URL = "https://iniche.cn/search?keyword=%s";
    private AgentWeb mAgentWeb;
    private Toolbar mToolbar;

    public static void startMain(Context context) {
        start(context, MAIN_URL);
    }

    public static void starSearch(Context context, String name) {
        try {
            start(context, String.format(SEARCH_URL, URLEncoder.encode(name, "UTF-8")));
        } catch (UnsupportedEncodingException ignored) {
        }
    }

    private static void start(Context context, String url) {
        Intent intent = new Intent(context, WebActivity.class);
        intent.setData(Uri.parse(url));
        context.startActivity(intent);
    }

    private static void syncCookies() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            CookieSyncManager.getInstance().sync();
            return;
        }
        AsyncTask.SERIAL_EXECUTOR.execute(() -> CookieManager.getInstance().flush());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);
        initView();
        Intent intent = getIntent();
        Uri data = intent.getData();
        if (data == null) {
            finish();
            return;
        }

        NestedScrollAgentWebView webView = new NestedScrollAgentWebView(this);
        CoordinatorLayout.LayoutParams layoutParams = new CoordinatorLayout.LayoutParams(-1, -1);
        layoutParams.setBehavior(new AppBarLayout.ScrollingViewBehavior());

        mAgentWeb = AgentWeb.with(this)
                .setAgentWebParent(findViewById(R.id.main), 1, layoutParams)
                .useDefaultIndicator()
                .setWebView(webView)
                .setWebViewClient(new WebViewClient() {

                    @SuppressWarnings("deprecation")
                    @Override
                    public boolean shouldOverrideUrlLoading(WebView view, String url) {
                        return shouldOverrideUrlLoading(Uri.parse(url));
                    }

                    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
                    @Override
                    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                        return shouldOverrideUrlLoading(request.getUrl());
                    }

                    @Override
                    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                        Log.w(TAG, "onReceivedSslError: " + error.toString());
                        handler.proceed();
                    }

                    private boolean shouldOverrideUrlLoading(Uri url) {
                        String scheme = url.getScheme();
                        if ("wtloginmqq".equalsIgnoreCase(scheme)) {
                            Uri.Builder builder = url.buildUpon();
                            builder.clearQuery();
                            for (String name : url.getQueryParameterNames()) {
                                if ("p".equalsIgnoreCase(name)) {
                                    Uri pUri = Uri.parse(url.getQueryParameter(name));
                                    Uri.Builder pBuild = pUri.buildUpon();
                                    pBuild.clearQuery();
                                    for (String pName : pUri.getQueryParameterNames()) {
                                        if ("pt_browser".equalsIgnoreCase(pName)) {
                                            pBuild.appendQueryParameter(pName, "JL-Iniche");
                                        } else {
                                            pBuild.appendQueryParameter(pName, pUri.getQueryParameter(pName));
                                        }
                                    }
                                    builder.appendQueryParameter(name, pBuild.toString());
                                } else {
                                    builder.appendQueryParameter(name, url.getQueryParameter(name));
                                }
                            }
                            builder.appendQueryParameter("schemacallback", "jliniche://");
                            url = builder.build();
                            try {
                                Intent qq = new Intent();
                                qq.setAction(Intent.ACTION_VIEW);
                                qq.setData(url);
                                startActivityForResult(qq, 100);
                            } catch (Exception e) {
                                Toast.makeText(WebActivity.this, "启动QQ失败, 请安装最新版QQ!", Toast.LENGTH_SHORT).show();
                            }
                            return true;
                        }
                        return false;
                    }
                })
                .setWebChromeClient(new WebChromeClient() {
                    @Override
                    public void onReceivedTitle(WebView view, String title) {
                        mToolbar.setTitle(title);
                        super.onReceivedTitle(view, title);
                    }
                })
                .setAgentWebWebSettings(new AbsAgentWebSettings() {

                    private AgentWeb mAgentWeb;

                    @Override
                    protected void bindAgentWebSupport(AgentWeb agentWeb) {
                        mAgentWeb = agentWeb;
                    }

                    @Override
                    public IAgentWebSettings<?> toSetting(WebView webView) {
                        super.toSetting(webView);
                        getWebSettings().setUserAgentString(StringUtils.USER_AGENT);
                        CookieManager cookieManager = CookieManager.getInstance();
                        if (cookieManager != null) {
                            cookieManager.setAcceptCookie(true);
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                cookieManager.setAcceptThirdPartyCookies(webView, true);
                            }
                        }

                        return this;
                    }

                    @Override
                    public WebListenerManager setDownloader(WebView webView, DownloadListener downloadListener) {
                        return super.setDownloader(webView, new DefaultDownloadImpl(WebActivity.this, webView, mAgentWeb.getPermissionInterceptor()) {

                            private String mUserAgent;
                            private String mContentDisposition;

                            @Override
                            protected void onDownloadStartInternal(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
                                mUserAgent = TextUtils.isEmpty(userAgent) ? webView.getSettings().getUserAgentString() : userAgent;
                                mContentDisposition = contentDisposition;
                                super.onDownloadStartInternal(url, userAgent, contentDisposition, mimetype, contentLength);
                            }

                            @Override
                            protected ResourceRequest<?> createResourceRequest(String url) {

                                File target = new File(Config.getDownloadDir());
                                if (!target.exists() || !target.isDirectory()) {
                                    //noinspection ResultOfMethodCallIgnored
                                    target.mkdirs();
                                }


                                ResourceRequest<?> request = super.createResourceRequest(url)
                                        .setUniquePath(false)
                                        .setQuickProgress(true)
                                        .setParallelDownload(false)
                                        .setOpenBreakPointDownload(false)
                                        .setRetry(0)
                                        .target(target, ContextHolder.getAppContext().getPackageName() + ".provider")
                                        .addHeader("User-Agent", mUserAgent);


                                DownloadTask downloadTask = request.getDownloadTask();
                                try {
                                    Method method = downloadTask.getClass().getDeclaredMethod("setContentDisposition", String.class);
                                    method.setAccessible(true);
                                    method.invoke(downloadTask, mContentDisposition);
                                } catch (Throwable e) {
                                    e.printStackTrace();
                                }
                                return request;
                            }

                            @Override
                            protected void taskEnqueue(ResourceRequest resourceRequest) {

                                resourceRequest.enqueue(new DownloadListenerAdapter() {

                                    @Override
                                    public void onStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength, Extra extra) {
                                        Toast.makeText(WebActivity.this, "正在下载, 请到通知栏看下载进度", Toast.LENGTH_SHORT).show();
                                        super.onStart(url, userAgent, contentDisposition, mimetype, contentLength, extra);
                                    }

                                    @Override
                                    public void onProgress(String url, long downloaded, long length, long usedTime) {
                                        super.onProgress(url, downloaded, length, usedTime);
                                    }

                                    @Override
                                    public boolean onResult(Throwable throwable, Uri path, String url, Extra extra) {

                                        if (throwable != null) {
                                            //noinspection ResultOfMethodCallIgnored
                                            ((DownloadTask) extra).getFile().delete();
                                            int status = ((DownloadTask) extra).getStatus();
                                            if (status == DownloadTask.STATUS_CANCELED) {
                                                Toast.makeText(WebActivity.this, "下载已取消", Toast.LENGTH_SHORT).show();
                                            } else if (status == DownloadTask.STATUS_ERROR) {
                                                Toast.makeText(WebActivity.this, "下载失败: " + throwable.getMessage(), Toast.LENGTH_SHORT).show();
                                            }
                                            return true;
                                        }

                                        String pathMatcher = path.toString().toLowerCase();

                                        // don't intercept apk file
                                        if (pathMatcher.endsWith(".apk")) return false;

                                        if (pathMatcher.endsWith(".jar")) {
                                            WebActivity.this.startActivity(new Intent(
                                                    Intent.ACTION_VIEW, path,
                                                    ContextHolder.getAppContext(), MainActivity.class)
                                            );
                                            return true;
                                        }
                                        Toast.makeText(WebActivity.this, "格式不被支持, 请下载J2ME类型程序!", Toast.LENGTH_LONG).show();
                                        return true;
                                    }
                                });
                            }
                        });
                    }
                })
                .setOpenOtherPageWays(DefaultWebClient.OpenOtherPageWays.DERECT)
                .createAgentWeb()
                .ready()
                .go(data.toString());

    }

    private void initView() {
        mToolbar = findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
        mToolbar.setNavigationOnClickListener(v -> WebActivity.this.finish());
    }

    @Override
    public void onBackPressed() {
        if (mAgentWeb.getWebCreator().getWebView().canGoBack()) {
            mAgentWeb.back();
            return;
        }
        super.onBackPressed();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.i(TAG, "onNewIntent: " + intent);
        Uri uri = intent == null ? null : intent.getData();
        if (uri != null && uri.getScheme().toLowerCase().startsWith("http")) {
            mAgentWeb.getUrlLoader().loadUrl(uri.toString());
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        mAgentWeb.getWebLifeCycle().onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mAgentWeb.getWebLifeCycle().onPause();
        syncCookies();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mAgentWeb.getWebLifeCycle().onDestroy();
    }
}
